"""
解码过程
从串口接收数据，进行特征提取之后进行解码，解码结果功光标界面调用
"""
import threading
import time
import numpy as np

from python_decoder import RunPython
from mat_decoder import RunMat


class MonkeyDecoder:
    def __init__(self, model_path, window_size=256, step_size=32, channel_num=60, fs=500, is_mat=True):

        self.window_size = window_size
        self.step_size = step_size
        self.channel_num = channel_num
        self.decoded_direction = -1
        self.data = np.zeros((self.step_size, self.channel_num), dtype=np.int16)
        self.is_mat = is_mat
        if self.is_mat:
            self.model = RunMat(model_path)
        else:
            self.model = RunPython(model_path, fs)

        # 解码线程
        self.decoding = False
        self.decode_thread = threading.Thread(target=self._decoding_loop, daemon=True)

    def start(self):
        if not self.decoding:
            self.decoding = True
            self.decode_thread.start()

    # 被串口函数调用：串口push解析后的数据
    def read_data(self, ecog_data):
        self.data = ecog_data
        # print("decode  read_data:", self.data[:,5])

    def _decoding_loop(self):
        sECoG_data_current = np.zeros((self.window_size, self.channel_num))
        while self.decoding:
            sECoG_matrix = self.data
            sECoG_data_current = np.concatenate((sECoG_data_current[self.step_size:, :], sECoG_matrix), axis=0)
            # 解码
            if self.is_mat:
                self.decoded_direction = self.decode_ecog_mat(sECoG_data_current)
            else:
                self.decoded_direction = self.decode_ecog(sECoG_data_current)  # 更新当前解码位置，被光标函数调用

    def decode_ecog(self, ecog_data):

        y_prob = self.model.run_model(ecog_data)

        return y_prob

    def decode_ecog_mat(self, ecog_data):
        """
        返回1的score
        :param ecog_data:
        :return:
        """
        # 测时间
        # start_time = time.time()
        score = self.model.run_model(ecog_data.T)
        # end_time = time.time()
        # print(f"预处理运行时间: {end_time - start_time:.6f} 秒")
        print("score:", score)
        # if score[0][0]>0.2:
        #     return 0
        # end_time1 = time.time()
        # print(f"解码运行时间: {end_time1 - end_time:.6f} 秒")
        return score

    def stop(self):
        self.decoding = False
        if self.decode_thread.is_alive():
            self.decode_thread.join()
        if self.is_mat:
            self.model.close()
